package jnzb.model.nzb;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;

/**
 * NZB file element
 * 
 * @author AA1
 * 
 */
public class File implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private NZB rootNZB;
	
	// Attributes
	private String poster;
	private int date;
	private String subject;
	private long size;
	private boolean decoded=false;

	private boolean ignore=false;
	
	// Children

	public File(NZB root) {
		this.rootNZB=root;
	}
	
	public NZB getRootNZB(){
		return rootNZB;
	}
	
	public String getPoster() {
		return poster;
	}

	public void setPoster(String poster) {
		this.poster = poster;
	}

	public int getDate() {
		return date;
	}

	public void setDate(int date) {
		this.date = date;
	}

	public String getSubject() {
		return subject;
	}

	public void setSubject(String subject) {
		this.subject = subject;
	}

	public List<String> getGroups() {
		return groups;
	}

	public void setGroups(List<String> groups) {
		this.groups = groups;
	}

	public List<Segment> getSegments() {
		return segments;
	}

	public void setSegments(List<Segment> segments) {
		this.segments = segments;
	}

	// This is a shortcut - should be 1 groups element containing multiple
	// groups, but whats the point?
	private List<String> groups;

	// Another shortcut - should be a segments element with lots of segment in
	private List<Segment> segments;

	private String outputFilename;

	private String absolutePath;

	public int getNumberOfGroups(){
		return this.groups.size();
	}
	
	public int getNumberOfSegments(){
		return this.segments.size();
	}
	
	/**
	 * @return true if all segments for this file have been downloaded
	 */
	public boolean allSegmentsDownloaded(){
		Iterator<Segment> i = segments.iterator();
		
		boolean allDownloaded=true;
		while (i.hasNext()){
			allDownloaded&=i.next().hasBeenDownloaded();
		}
		return allDownloaded;
	}

	/**
	 * Get the sum of the size of the segments
	 * @return
	 */
	public long getSize() {
		if (this.size==0){
			Iterator<Segment> s = segments.iterator();
			while(s.hasNext()){
				this.size+=s.next().getBytes();
			}
		}
		return size;
	}

	/**
	 * @return true is the file has been decoded
	 */
	public boolean isDecoded() {
		return decoded;
	}

	/**
	 * Sets the flag that indicates that the file has been decoded.<br>
	 * Note that this will all segments must have been downloaded for this to be true
	 * @param decoded
	 */
	public void setDecoded(boolean allDecoded) {
		this.decoded = allDecoded && this.allSegmentsDownloaded(); 
	}

	/**
	 * Calculates how many bytes are left to download in this file
	 * @return
	 */
	public long getBytesRemaining() {
		long totalRemaining=0;
		Iterator<Segment> s = segments.iterator();
		while(s.hasNext()){
			Segment segment = s.next();
			if (!segment.hasBeenDownloaded()){
				totalRemaining+=segment.getBytes();
			}
		}
		return totalRemaining;
	}
	
	
	/**
	 * Returns the number of bytes downloaded of this file 
	 * @return
	 */
	public long getProgress(){
		long totalProgress=0;
		Iterator<Segment> s = segments.iterator();
		while(s.hasNext()){
			Segment segment = s.next();
			if (segment.hasBeenDownloaded()){
				totalProgress+=segment.getBytes();
			}
		}
		return totalProgress;		
	}

	/**
	 * @return the ignore
	 */
	public boolean isIgnore() {
		return ignore;
	}

	/**
	 * @param ignore the ignore to set
	 */
	public void setIgnore(boolean ignore) {
		this.ignore = ignore;
	}

	/**
	 * Set the output filename of the file
	 * @param outputFilename
	 */
	public void setOutputFilename(String outputFilename) {
		this.outputFilename = outputFilename;
		
	}

	/**
	 * @return the outputFilename
	 */
	public String getOutputFilename() {
		return outputFilename;
	}

	/**
	 * @return the absolutePath
	 */
	public String getAbsolutePath() {
		return absolutePath;
	}

	/**
	 * Set the absolute path for this file
	 * @param outputPath
	 */
	public void setAbsolutePath(String absolutePath) {
		this.absolutePath = absolutePath;
	}
}
